// Copyright 2021 Datafuse Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This code is generated by src/query/codegen/src/writes/register.rs. DO NOT EDIT.

#![allow(unused_parens)]
#![allow(unused_variables)]
#![allow(clippy::redundant_closure)]
use crate::property::Domain;
use crate::types::nullable::NullableColumn;
use crate::types::nullable::NullableDomain;
use crate::types::*;
use crate::values::Value;
use crate::values::ValueRef;
use crate::EvalContext;
use crate::Function;
use crate::FunctionContext;
use crate::FunctionDomain;
use crate::FunctionEval;
use crate::FunctionRegistry;
use crate::FunctionSignature;

impl FunctionRegistry {
    pub fn register_1_arg<I1: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: Fn(I1::ScalarRef<'_>, &mut EvalContext) -> O::Scalar
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        self.register_passthrough_nullable_1_arg::<I1, O, _, _>(
            name,
            calc_domain,
            vectorize_1_arg(func),
        )
    }

    pub fn register_2_arg<I1: ArgType, I2: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: Fn(I1::ScalarRef<'_>, I2::ScalarRef<'_>, &mut EvalContext) -> O::Scalar
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        self.register_passthrough_nullable_2_arg::<I1, I2, O, _, _>(
            name,
            calc_domain,
            vectorize_2_arg(func),
        )
    }

    pub fn register_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain, &I3::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: Fn(
                I1::ScalarRef<'_>,
                I2::ScalarRef<'_>,
                I3::ScalarRef<'_>,
                &mut EvalContext,
            ) -> O::Scalar
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        self.register_passthrough_nullable_3_arg::<I1, I2, I3, O, _, _>(
            name,
            calc_domain,
            vectorize_3_arg(func),
        )
    }

    pub fn register_4_arg<I1: ArgType, I2: ArgType, I3: ArgType, I4: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: Fn(
                I1::ScalarRef<'_>,
                I2::ScalarRef<'_>,
                I3::ScalarRef<'_>,
                I4::ScalarRef<'_>,
                &mut EvalContext,
            ) -> O::Scalar
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        self.register_passthrough_nullable_4_arg::<I1, I2, I3, I4, O, _, _>(
            name,
            calc_domain,
            vectorize_4_arg(func),
        )
    }

    pub fn register_5_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        I5: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
                &I5::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: Fn(
                I1::ScalarRef<'_>,
                I2::ScalarRef<'_>,
                I3::ScalarRef<'_>,
                I4::ScalarRef<'_>,
                I5::ScalarRef<'_>,
                &mut EvalContext,
            ) -> O::Scalar
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        self.register_passthrough_nullable_5_arg::<I1, I2, I3, I4, I5, O, _, _>(
            name,
            calc_domain,
            vectorize_5_arg(func),
        )
    }

    pub fn register_passthrough_nullable_1_arg<I1: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[I1::data_type(), O::data_type()]
            .iter()
            .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_1_arg_core instead",
            name
        );

        self.register_1_arg_core::<I1, O, _, _>(name, calc_domain, func);

        self.register_1_arg_core::<NullableType<I1>, NullableType<O>, _, _>(
            name,
            move |ctx, arg1| match (&arg1.value) {
                (Some(value1)) => {
                    if let Some(domain) = calc_domain(ctx, value1).normalize() {
                        FunctionDomain::Domain(NullableDomain {
                            has_null: arg1.has_null,
                            value: Some(Box::new(domain)),
                        })
                    } else {
                        FunctionDomain::MayThrow
                    }
                }
                _ => FunctionDomain::Domain(NullableDomain {
                    has_null: true,
                    value: None,
                }),
            },
            passthrough_nullable_1_arg(func),
        );
    }

    pub fn register_passthrough_nullable_2_arg<I1: ArgType, I2: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(ValueRef<'a, I1>, ValueRef<'a, I2>, &mut EvalContext) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[I1::data_type(), I2::data_type(), O::data_type()]
            .iter()
            .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_2_arg_core instead",
            name
        );

        self.register_2_arg_core::<I1, I2, O, _, _>(name, calc_domain, func);

        self.register_2_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<O>, _, _>(
            name,
            move |ctx, arg1, arg2| match (&arg1.value, &arg2.value) {
                (Some(value1), Some(value2)) => {
                    if let Some(domain) = calc_domain(ctx, value1, value2).normalize() {
                        FunctionDomain::Domain(NullableDomain {
                            has_null: arg1.has_null || arg2.has_null,
                            value: Some(Box::new(domain)),
                        })
                    } else {
                        FunctionDomain::MayThrow
                    }
                }
                _ => FunctionDomain::Domain(NullableDomain {
                    has_null: true,
                    value: None,
                }),
            },
            passthrough_nullable_2_arg(func),
        );
    }

    pub fn register_passthrough_nullable_3_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain, &I3::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_3_arg_core instead",
            name
        );

        self.register_3_arg_core::<I1, I2, I3, O, _, _>(name, calc_domain, func);

        self.register_3_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,| {
                            match (&arg1.value,&arg2.value,&arg3.value) {
                                (Some(value1),Some(value2),Some(value3)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null,
                                            value: Some(Box::new(domain)),
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                },
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        passthrough_nullable_3_arg(func),
                    );
    }

    pub fn register_passthrough_nullable_4_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            I4::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_4_arg_core instead",
            name
        );

        self.register_4_arg_core::<I1, I2, I3, I4, O, _, _>(name, calc_domain, func);

        self.register_4_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>, NullableType<I4>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,arg4,| {
                            match (&arg1.value,&arg2.value,&arg3.value,&arg4.value) {
                                (Some(value1),Some(value2),Some(value3),Some(value4)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,value4,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null||arg4.has_null,
                                            value: Some(Box::new(domain)),
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                },
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        passthrough_nullable_4_arg(func),
                    );
    }

    pub fn register_passthrough_nullable_5_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        I5: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
                &I5::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                ValueRef<'a, I5>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            I4::data_type(),
            I5::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_5_arg_core instead",
            name
        );

        self.register_5_arg_core::<I1, I2, I3, I4, I5, O, _, _>(name, calc_domain, func);

        self.register_5_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>, NullableType<I4>, NullableType<I5>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,arg4,arg5,| {
                            match (&arg1.value,&arg2.value,&arg3.value,&arg4.value,&arg5.value) {
                                (Some(value1),Some(value2),Some(value3),Some(value4),Some(value5)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,value4,value5,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null||arg4.has_null||arg5.has_null,
                                            value: Some(Box::new(domain)),
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                },
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        passthrough_nullable_5_arg(func),
                    );
    }

    pub fn register_combine_nullable_1_arg<I1: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain) -> FunctionDomain<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[I1::data_type(), O::data_type()]
            .iter()
            .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_1_arg_core instead",
            name
        );

        self.register_1_arg_core::<I1, NullableType<O>, _, _>(name, calc_domain, func);

        self.register_1_arg_core::<NullableType<I1>, NullableType<O>, _, _>(
            name,
            move |ctx, arg1| match (&arg1.value) {
                (Some(value1)) => {
                    if let Some(domain) = calc_domain(ctx, value1).normalize() {
                        FunctionDomain::Domain(NullableDomain {
                            has_null: arg1.has_null || domain.has_null,
                            value: domain.value,
                        })
                    } else {
                        FunctionDomain::MayThrow
                    }
                }
                _ => FunctionDomain::Domain(NullableDomain {
                    has_null: true,
                    value: None,
                }),
            },
            combine_nullable_1_arg(func),
        );
    }

    pub fn register_combine_nullable_2_arg<I1: ArgType, I2: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain) -> FunctionDomain<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                &mut EvalContext,
            ) -> Value<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[I1::data_type(), I2::data_type(), O::data_type()]
            .iter()
            .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_2_arg_core instead",
            name
        );

        self.register_2_arg_core::<I1, I2, NullableType<O>, _, _>(name, calc_domain, func);

        self.register_2_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<O>, _, _>(
            name,
            move |ctx, arg1, arg2| match (&arg1.value, &arg2.value) {
                (Some(value1), Some(value2)) => {
                    if let Some(domain) = calc_domain(ctx, value1, value2).normalize() {
                        FunctionDomain::Domain(NullableDomain {
                            has_null: arg1.has_null || arg2.has_null || domain.has_null,
                            value: domain.value,
                        })
                    } else {
                        FunctionDomain::MayThrow
                    }
                }
                _ => FunctionDomain::Domain(NullableDomain {
                    has_null: true,
                    value: None,
                }),
            },
            combine_nullable_2_arg(func),
        );
    }

    pub fn register_combine_nullable_3_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
            ) -> FunctionDomain<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                &mut EvalContext,
            ) -> Value<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_3_arg_core instead",
            name
        );

        self.register_3_arg_core::<I1, I2, I3, NullableType<O>, _, _>(name, calc_domain, func);

        self.register_3_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,| {
                            match (&arg1.value,&arg2.value,&arg3.value) {
                                (Some(value1),Some(value2),Some(value3)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null || domain.has_null,
                                            value: domain.value,
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                }
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        combine_nullable_3_arg(func),
                    );
    }

    pub fn register_combine_nullable_4_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
            ) -> FunctionDomain<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                &mut EvalContext,
            ) -> Value<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            I4::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_4_arg_core instead",
            name
        );

        self.register_4_arg_core::<I1, I2, I3, I4, NullableType<O>, _, _>(name, calc_domain, func);

        self.register_4_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>, NullableType<I4>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,arg4,| {
                            match (&arg1.value,&arg2.value,&arg3.value,&arg4.value) {
                                (Some(value1),Some(value2),Some(value3),Some(value4)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,value4,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null||arg4.has_null || domain.has_null,
                                            value: domain.value,
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                }
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        combine_nullable_4_arg(func),
                    );
    }

    pub fn register_combine_nullable_5_arg<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        I5: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
                &I5::Domain,
            ) -> FunctionDomain<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                ValueRef<'a, I5>,
                &mut EvalContext,
            ) -> Value<NullableType<O>>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let has_nullable = &[
            I1::data_type(),
            I2::data_type(),
            I3::data_type(),
            I4::data_type(),
            I5::data_type(),
            O::data_type(),
        ]
        .iter()
        .any(|ty| ty.as_nullable().is_some() || ty.is_null());

        assert!(
            !has_nullable,
            "Function {} has nullable argument or output, please use register_5_arg_core instead",
            name
        );

        self.register_5_arg_core::<I1, I2, I3, I4, I5, NullableType<O>, _, _>(
            name,
            calc_domain,
            func,
        );

        self.register_5_arg_core::<NullableType<I1>, NullableType<I2>, NullableType<I3>, NullableType<I4>, NullableType<I5>,  NullableType<O>, _, _>(
                        name,
                        move |ctx, arg1,arg2,arg3,arg4,arg5,| {
                            match (&arg1.value,&arg2.value,&arg3.value,&arg4.value,&arg5.value) {
                                (Some(value1),Some(value2),Some(value3),Some(value4),Some(value5)) => {
                                    if let Some(domain) = calc_domain(ctx, value1,value2,value3,value4,value5,).normalize() {
                                        FunctionDomain::Domain(NullableDomain {
                                            has_null: arg1.has_null||arg2.has_null||arg3.has_null||arg4.has_null||arg5.has_null || domain.has_null,
                                            value: domain.value,
                                        })
                                    } else {
                                        FunctionDomain::MayThrow
                                    }
                                }
                                _ => {
                                    FunctionDomain::Domain(NullableDomain {
                                        has_null: true,
                                        value: None,
                                    })
                                },
                            }
                        },
                        combine_nullable_5_arg(func),
                    );
    }

    pub fn register_0_arg_core<O: ArgType, F, G>(&mut self, name: &str, calc_domain: F, func: G)
    where
        F: Fn(&FunctionContext) -> FunctionDomain<O> + 'static + Clone + Copy + Send + Sync,
        G: for<'a> Fn(&mut EvalContext) -> Value<O> + 'static + Clone + Copy + Send + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_0_arg::<O>(calc_domain)),
                eval: Box::new(erase_function_generic_0_arg(func)),
            },
        };
        self.register_function(func);
    }

    pub fn register_1_arg_core<I1: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![I1::data_type()],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_1_arg::<I1, O>(calc_domain)),
                eval: Box::new(erase_function_generic_1_arg(func)),
            },
        };
        self.register_function(func);
    }

    pub fn register_2_arg_core<I1: ArgType, I2: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(ValueRef<'a, I1>, ValueRef<'a, I2>, &mut EvalContext) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![I1::data_type(), I2::data_type()],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_2_arg::<I1, I2, O>(calc_domain)),
                eval: Box::new(erase_function_generic_2_arg(func)),
            },
        };
        self.register_function(func);
    }

    pub fn register_3_arg_core<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType, F, G>(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(&FunctionContext, &I1::Domain, &I2::Domain, &I3::Domain) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![I1::data_type(), I2::data_type(), I3::data_type()],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_3_arg::<I1, I2, I3, O>(
                    calc_domain,
                )),
                eval: Box::new(erase_function_generic_3_arg(func)),
            },
        };
        self.register_function(func);
    }

    pub fn register_4_arg_core<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![
                    I1::data_type(),
                    I2::data_type(),
                    I3::data_type(),
                    I4::data_type(),
                ],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_4_arg::<I1, I2, I3, I4, O>(
                    calc_domain,
                )),
                eval: Box::new(erase_function_generic_4_arg(func)),
            },
        };
        self.register_function(func);
    }

    pub fn register_5_arg_core<
        I1: ArgType,
        I2: ArgType,
        I3: ArgType,
        I4: ArgType,
        I5: ArgType,
        O: ArgType,
        F,
        G,
    >(
        &mut self,
        name: &str,
        calc_domain: F,
        func: G,
    ) where
        F: Fn(
                &FunctionContext,
                &I1::Domain,
                &I2::Domain,
                &I3::Domain,
                &I4::Domain,
                &I5::Domain,
            ) -> FunctionDomain<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
        G: for<'a> Fn(
                ValueRef<'a, I1>,
                ValueRef<'a, I2>,
                ValueRef<'a, I3>,
                ValueRef<'a, I4>,
                ValueRef<'a, I5>,
                &mut EvalContext,
            ) -> Value<O>
            + 'static
            + Clone
            + Copy
            + Send
            + Sync,
    {
        let func = Function {
            signature: FunctionSignature {
                name: name.to_string(),
                args_type: vec![
                    I1::data_type(),
                    I2::data_type(),
                    I3::data_type(),
                    I4::data_type(),
                    I5::data_type(),
                ],
                return_type: O::data_type(),
            },
            eval: FunctionEval::Scalar {
                calc_domain: Box::new(erase_calc_domain_generic_5_arg::<I1, I2, I3, I4, I5, O>(
                    calc_domain,
                )),
                eval: Box::new(erase_function_generic_5_arg(func)),
            },
        };
        self.register_function(func);
    }
}

pub fn vectorize_1_arg<I1: ArgType, O: ArgType>(
    func: impl Fn(I1::ScalarRef<'_>, &mut EvalContext) -> O::Scalar + Copy + Send + Sync,
) -> impl Fn(ValueRef<I1>, &mut EvalContext) -> Value<O> + Copy + Send + Sync {
    move |arg1, ctx| match (arg1) {
        (ValueRef::Scalar(arg1)) => Value::Scalar(func(arg1, ctx)),
        (ValueRef::Column(arg1)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter.map(|arg1| func(arg1, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
    }
}

pub fn vectorize_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl Fn(I1::ScalarRef<'_>, I2::ScalarRef<'_>, &mut EvalContext) -> O::Scalar
    + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, &mut EvalContext) -> Value<O> + Copy + Send + Sync {
    move |arg1, arg2, ctx| match (arg1, arg2) {
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2)) => Value::Scalar(func(arg1, arg2, ctx)),
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter.map(|arg1| func(arg1, arg2.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter.map(|arg2| func(arg1.clone(), arg2, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter
                .zip(arg2_iter)
                .map(|(arg1, arg2)| func(arg1, arg2, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
    }
}

pub fn vectorize_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        &mut EvalContext,
    ) -> O::Scalar
    + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, ValueRef<I3>, &mut EvalContext) -> Value<O> + Copy + Send + Sync
{
    move |arg1, arg2, arg3, ctx| match (arg1, arg2, arg3) {
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ValueRef::Scalar(arg3)) => {
            Value::Scalar(func(arg1, arg2, arg3, ctx))
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter.map(|arg1| func(arg1, arg2.clone(), arg3.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter.map(|arg2| func(arg1.clone(), arg2, arg3.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter
                .zip(arg2_iter)
                .map(|(arg1, arg2)| func(arg1, arg2, arg3.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg3_iter.map(|arg3| func(arg1.clone(), arg2.clone(), arg3, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter
                .zip(arg3_iter)
                .map(|(arg1, arg3)| func(arg1, arg2.clone(), arg3, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter
                .zip(arg3_iter)
                .map(|(arg2, arg3)| func(arg1.clone(), arg2, arg3, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .map(|((arg1, arg2), arg3)| func(arg1, arg2, arg3, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
    }
}

pub fn vectorize_4_arg<I1: ArgType, I2: ArgType, I3: ArgType, I4: ArgType, O: ArgType>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        I4::ScalarRef<'_>,
        &mut EvalContext,
    ) -> O::Scalar
    + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, ValueRef<I3>, ValueRef<I4>, &mut EvalContext) -> Value<O>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, ctx| match (arg1, arg2, arg3, arg4) {
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => Value::Scalar(func(arg1, arg2, arg3, arg4, ctx)),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter =
                arg1_iter.map(|arg1| func(arg1, arg2.clone(), arg3.clone(), arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter =
                arg2_iter.map(|arg2| func(arg1.clone(), arg2, arg3.clone(), arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter
                .zip(arg2_iter)
                .map(|(arg1, arg2)| func(arg1, arg2, arg3.clone(), arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter =
                arg3_iter.map(|arg3| func(arg1.clone(), arg2.clone(), arg3, arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter
                .zip(arg3_iter)
                .map(|(arg1, arg3)| func(arg1, arg2.clone(), arg3, arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter
                .zip(arg3_iter)
                .map(|(arg2, arg3)| func(arg1.clone(), arg2, arg3, arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .map(|((arg1, arg2), arg3)| func(arg1, arg2, arg3, arg4.clone(), ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let iter =
                arg4_iter.map(|arg4| func(arg1.clone(), arg2.clone(), arg3.clone(), arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg4_iter)
                .map(|(arg1, arg4)| func(arg1, arg2.clone(), arg3.clone(), arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter
                .zip(arg4_iter)
                .map(|(arg2, arg4)| func(arg1.clone(), arg2, arg3.clone(), arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg4_iter)
                .map(|((arg1, arg2), arg4)| func(arg1, arg2, arg3.clone(), arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg3_iter
                .zip(arg4_iter)
                .map(|(arg3, arg4)| func(arg1.clone(), arg2.clone(), arg3, arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg3_iter)
                .zip(arg4_iter)
                .map(|((arg1, arg3), arg4)| func(arg1, arg2.clone(), arg3, arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter
                .zip(arg3_iter)
                .zip(arg4_iter)
                .map(|((arg2, arg3), arg4)| func(arg1.clone(), arg2, arg3, arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .zip(arg4_iter)
                .map(|(((arg1, arg2), arg3), arg4)| func(arg1, arg2, arg3, arg4, ctx));
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
    }
}

pub fn vectorize_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        I4::ScalarRef<'_>,
        I5::ScalarRef<'_>,
        &mut EvalContext,
    ) -> O::Scalar
    + Copy
    + Send
    + Sync,
) -> impl Fn(
    ValueRef<I1>,
    ValueRef<I2>,
    ValueRef<I3>,
    ValueRef<I4>,
    ValueRef<I5>,
    &mut EvalContext,
) -> Value<O>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, arg5, ctx| match (arg1, arg2, arg3, arg4, arg5) {
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => Value::Scalar(func(arg1, arg2, arg3, arg4, arg5, ctx)),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter.map(|arg1| {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    arg5.clone(),
                    ctx,
                )
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter.map(|arg2| {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    arg5.clone(),
                    ctx,
                )
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter.zip(arg2_iter).map(|(arg1, arg2)| {
                func(arg1, arg2, arg3.clone(), arg4.clone(), arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg3_iter.map(|arg3| {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    arg5.clone(),
                    ctx,
                )
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg3_iter).map(|(arg1, arg3)| {
                func(arg1, arg2.clone(), arg3, arg4.clone(), arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter.zip(arg3_iter).map(|(arg2, arg3)| {
                func(arg1.clone(), arg2, arg3, arg4.clone(), arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .map(|((arg1, arg2), arg3)| {
                    func(arg1, arg2, arg3, arg4.clone(), arg5.clone(), ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg4_iter.map(|arg4| {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    arg5.clone(),
                    ctx,
                )
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg4_iter).map(|(arg1, arg4)| {
                func(arg1, arg2.clone(), arg3.clone(), arg4, arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter.zip(arg4_iter).map(|(arg2, arg4)| {
                func(arg1.clone(), arg2, arg3.clone(), arg4, arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg4_iter)
                .map(|((arg1, arg2), arg4)| {
                    func(arg1, arg2, arg3.clone(), arg4, arg5.clone(), ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg3_iter.zip(arg4_iter).map(|(arg3, arg4)| {
                func(arg1.clone(), arg2.clone(), arg3, arg4, arg5.clone(), ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter
                .zip(arg3_iter)
                .zip(arg4_iter)
                .map(|((arg1, arg3), arg4)| {
                    func(arg1, arg2.clone(), arg3, arg4, arg5.clone(), ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter
                .zip(arg3_iter)
                .zip(arg4_iter)
                .map(|((arg2, arg3), arg4)| {
                    func(arg1.clone(), arg2, arg3, arg4, arg5.clone(), ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter).zip(arg4_iter).map(
                |(((arg1, arg2), arg3), arg4)| func(arg1, arg2, arg3, arg4, arg5.clone(), ctx),
            );
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg5_iter.map(|arg5| {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    arg5,
                    ctx,
                )
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg5_iter).map(|(arg1, arg5)| {
                func(arg1, arg2.clone(), arg3.clone(), arg4.clone(), arg5, ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg5_iter).map(|(arg2, arg5)| {
                func(arg1.clone(), arg2, arg3.clone(), arg4.clone(), arg5, ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg5_iter)
                .map(|((arg1, arg2), arg5)| {
                    func(arg1, arg2, arg3.clone(), arg4.clone(), arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg3_iter.zip(arg5_iter).map(|(arg3, arg5)| {
                func(arg1.clone(), arg2.clone(), arg3, arg4.clone(), arg5, ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter
                .zip(arg3_iter)
                .zip(arg5_iter)
                .map(|((arg1, arg3), arg5)| {
                    func(arg1, arg2.clone(), arg3, arg4.clone(), arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter
                .zip(arg3_iter)
                .zip(arg5_iter)
                .map(|((arg2, arg3), arg5)| {
                    func(arg1.clone(), arg2, arg3, arg4.clone(), arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter).zip(arg5_iter).map(
                |(((arg1, arg2), arg3), arg5)| func(arg1, arg2, arg3, arg4.clone(), arg5, ctx),
            );
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg4_iter.zip(arg5_iter).map(|(arg4, arg5)| {
                func(arg1.clone(), arg2.clone(), arg3.clone(), arg4, arg5, ctx)
            });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter
                .zip(arg4_iter)
                .zip(arg5_iter)
                .map(|((arg1, arg4), arg5)| {
                    func(arg1, arg2.clone(), arg3.clone(), arg4, arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter
                .zip(arg4_iter)
                .zip(arg5_iter)
                .map(|((arg2, arg4), arg5)| {
                    func(arg1.clone(), arg2, arg3.clone(), arg4, arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg2_iter).zip(arg4_iter).zip(arg5_iter).map(
                |(((arg1, arg2), arg4), arg5)| func(arg1, arg2, arg3.clone(), arg4, arg5, ctx),
            );
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg3_iter
                .zip(arg4_iter)
                .zip(arg5_iter)
                .map(|((arg3, arg4), arg5)| {
                    func(arg1.clone(), arg2.clone(), arg3, arg4, arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg3_iter).zip(arg4_iter).zip(arg5_iter).map(
                |(((arg1, arg3), arg4), arg5)| func(arg1, arg2.clone(), arg3, arg4, arg5, ctx),
            );
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg3_iter).zip(arg4_iter).zip(arg5_iter).map(
                |(((arg2, arg3), arg4), arg5)| func(arg1.clone(), arg2, arg3, arg4, arg5, ctx),
            );
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .zip(arg4_iter)
                .zip(arg5_iter)
                .map(|((((arg1, arg2), arg3), arg4), arg5)| {
                    func(arg1, arg2, arg3, arg4, arg5, ctx)
                });
            let col = O::column_from_iter(iter, generics);
            Value::Column(col)
        }
    }
}

pub fn vectorize_with_builder_1_arg<I1: ArgType, O: ArgType>(
    func: impl Fn(I1::ScalarRef<'_>, &mut O::ColumnBuilder, &mut EvalContext) + Copy + Send + Sync,
) -> impl Fn(ValueRef<I1>, &mut EvalContext) -> Value<O> + Copy + Send + Sync {
    move |arg1, ctx| match (arg1) {
        (ValueRef::Scalar(arg1)) => {
            let generics = &(ctx.generics.to_owned());
            let mut builder = O::create_builder(1, generics);
            func(arg1, &mut builder, ctx);
            Value::Scalar(O::build_scalar(builder))
        }
        (ValueRef::Column(arg1)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg1 in iter {
                func(arg1, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
    }
}

pub fn vectorize_with_builder_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl Fn(I1::ScalarRef<'_>, I2::ScalarRef<'_>, &mut O::ColumnBuilder, &mut EvalContext)
    + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, &mut EvalContext) -> Value<O> + Copy + Send + Sync {
    move |arg1, arg2, ctx| match (arg1, arg2) {
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let mut builder = O::create_builder(1, generics);
            func(arg1, arg2, &mut builder, ctx);
            Value::Scalar(O::build_scalar(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg1 in iter {
                func(arg1, arg2.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg2 in iter {
                func(arg1.clone(), arg2, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter.zip(arg2_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg2) in iter {
                func(arg1, arg2, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
    }
}

pub fn vectorize_with_builder_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        &mut O::ColumnBuilder,
        &mut EvalContext,
    ) + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, ValueRef<I3>, &mut EvalContext) -> Value<O> + Copy + Send + Sync
{
    move |arg1, arg2, arg3, ctx| match (arg1, arg2, arg3) {
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let mut builder = O::create_builder(1, generics);
            func(arg1, arg2, arg3, &mut builder, ctx);
            Value::Scalar(O::build_scalar(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg1 in iter {
                func(arg1, arg2.clone(), arg3.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg2 in iter {
                func(arg1.clone(), arg2, arg3.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Scalar(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter.zip(arg2_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg2) in iter {
                func(arg1, arg2, arg3.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg3_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg3 in iter {
                func(arg1.clone(), arg2.clone(), arg3, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg3) in iter {
                func(arg1, arg2.clone(), arg3, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Scalar(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg3) in iter {
                func(arg1.clone(), arg2, arg3, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg3) in iter {
                func(arg1, arg2, arg3, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
    }
}

pub fn vectorize_with_builder_4_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    O: ArgType,
>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        I4::ScalarRef<'_>,
        &mut O::ColumnBuilder,
        &mut EvalContext,
    ) + Copy
    + Send
    + Sync,
) -> impl Fn(ValueRef<I1>, ValueRef<I2>, ValueRef<I3>, ValueRef<I4>, &mut EvalContext) -> Value<O>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, ctx| match (arg1, arg2, arg3, arg4) {
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let mut builder = O::create_builder(1, generics);
            func(arg1, arg2, arg3, arg4, &mut builder, ctx);
            Value::Scalar(O::build_scalar(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg1 in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg2 in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter.zip(arg2_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg2) in iter {
                func(arg1, arg2, arg3.clone(), arg4.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg3_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg3 in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg3) in iter {
                func(arg1, arg2.clone(), arg3, arg4.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg3) in iter {
                func(arg1.clone(), arg2, arg3, arg4.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg3) in iter {
                func(arg1, arg2, arg3, arg4.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg4_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg4 in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg4) in iter {
                func(arg1, arg2.clone(), arg3.clone(), arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg4) in iter {
                func(arg1.clone(), arg2, arg3.clone(), arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg2_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg4) in iter {
                func(arg1, arg2, arg3.clone(), arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg3_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg3, arg4) in iter {
                func(arg1.clone(), arg2.clone(), arg3, arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg3), arg4) in iter {
                func(arg1, arg2.clone(), arg3, arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter.zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg2, arg3), arg4) in iter {
                func(arg1.clone(), arg2, arg3, arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg1, arg2), arg3), arg4) in iter {
                func(arg1, arg2, arg3, arg4, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
    }
}

pub fn vectorize_with_builder_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl Fn(
        I1::ScalarRef<'_>,
        I2::ScalarRef<'_>,
        I3::ScalarRef<'_>,
        I4::ScalarRef<'_>,
        I5::ScalarRef<'_>,
        &mut O::ColumnBuilder,
        &mut EvalContext,
    ) + Copy
    + Send
    + Sync,
) -> impl Fn(
    ValueRef<I1>,
    ValueRef<I2>,
    ValueRef<I3>,
    ValueRef<I4>,
    ValueRef<I5>,
    &mut EvalContext,
) -> Value<O>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, arg5, ctx| match (arg1, arg2, arg3, arg4, arg5) {
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let mut builder = O::create_builder(1, generics);
            func(arg1, arg2, arg3, arg4, arg5, &mut builder, ctx);
            Value::Scalar(O::build_scalar(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let iter = arg1_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg1 in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg2_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg2 in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let iter = arg1_iter.zip(arg2_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg2) in iter {
                func(
                    arg1,
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg3_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg3 in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg3) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg2_iter.zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg3) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3,
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg3) in iter {
                func(
                    arg1,
                    arg2,
                    arg3,
                    arg4.clone(),
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg4_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg4 in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg4) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg4) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg2_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg4) in iter {
                func(
                    arg1,
                    arg2,
                    arg3.clone(),
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg3_iter.zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg3, arg4) in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg3), arg4) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3,
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg2_iter.zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg2, arg3), arg4) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3,
                    arg4,
                    arg5.clone(),
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter).zip(arg4_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg1, arg2), arg3), arg4) in iter {
                func(arg1, arg2, arg3, arg4, arg5.clone(), &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg5_iter;
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for arg5 in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg1, arg5) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg2, arg5) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg2_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg2), arg5) in iter {
                func(
                    arg1,
                    arg2,
                    arg3.clone(),
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg3_iter.zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg3, arg5) in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg3_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg3), arg5) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3,
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg3_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg2, arg3), arg5) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3,
                    arg4.clone(),
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg2_iter).zip(arg3_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg1, arg2), arg3), arg5) in iter {
                func(arg1, arg2, arg3, arg4.clone(), arg5, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg4_iter.zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (arg4, arg5) in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg1, arg4), arg5) in iter {
                func(
                    arg1,
                    arg2.clone(),
                    arg3.clone(),
                    arg4,
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg2, arg4), arg5) in iter {
                func(
                    arg1.clone(),
                    arg2,
                    arg3.clone(),
                    arg4,
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg2_iter).zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg1, arg2), arg4), arg5) in iter {
                func(arg1, arg2, arg3.clone(), arg4, arg5, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg3_iter.zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((arg3, arg4), arg5) in iter {
                func(
                    arg1.clone(),
                    arg2.clone(),
                    arg3,
                    arg4,
                    arg5,
                    &mut builder,
                    ctx,
                );
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter.zip(arg3_iter).zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg1, arg3), arg4), arg5) in iter {
                func(arg1, arg2.clone(), arg3, arg4, arg5, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Scalar(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg2_iter.zip(arg3_iter).zip(arg4_iter).zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for (((arg2, arg3), arg4), arg5) in iter {
                func(arg1.clone(), arg2, arg3, arg4, arg5, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let generics = &(ctx.generics.to_owned());
            let arg1_iter = I1::iter_column(&arg1);
            let arg2_iter = I2::iter_column(&arg2);
            let arg3_iter = I3::iter_column(&arg3);
            let arg4_iter = I4::iter_column(&arg4);
            let arg5_iter = I5::iter_column(&arg5);
            let iter = arg1_iter
                .zip(arg2_iter)
                .zip(arg3_iter)
                .zip(arg4_iter)
                .zip(arg5_iter);
            let mut builder = O::create_builder(iter.size_hint().0, generics);
            for ((((arg1, arg2), arg3), arg4), arg5) in iter {
                func(arg1, arg2, arg3, arg4, arg5, &mut builder, ctx);
            }
            Value::Column(O::build_column(builder))
        }
    }
}

pub fn passthrough_nullable_1_arg<I1: ArgType, O: ArgType>(
    func: impl for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<O> + Copy + Send + Sync,
) -> impl for<'a> Fn(ValueRef<'a, NullableType<I1>>, &mut EvalContext) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, ctx| match (arg1) {
        (ValueRef::Scalar(None)) => Value::Scalar(None),
        (ValueRef::Scalar(Some(arg1))) => Value::Scalar(Some(
            func(ValueRef::Scalar(arg1), ctx).into_scalar().unwrap(),
        )),
        (ValueRef::Column(arg1)) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(ValueRef::Column(arg1.column), ctx)
                .into_column()
                .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
    }
}

pub fn passthrough_nullable_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl for<'a> Fn(ValueRef<'a, I1>, ValueRef<'a, I2>, &mut EvalContext) -> Value<O>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, ctx| match (arg1, arg2) {
        (ValueRef::Scalar(None), _) | (_, ValueRef::Scalar(None)) => Value::Scalar(None),
        (ValueRef::Scalar(Some(arg1)), ValueRef::Scalar(Some(arg2))) => Value::Scalar(Some(
            func(ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ctx)
                .into_scalar()
                .unwrap(),
        )),
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2))) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(ValueRef::Column(arg1.column), ValueRef::Scalar(arg2), ctx)
                .into_column()
                .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2)) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(ValueRef::Scalar(arg1), ValueRef::Column(arg2.column), ctx)
                .into_column()
                .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
    }
}

pub fn passthrough_nullable_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        &mut EvalContext,
    ) -> Value<O>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, ctx| match (arg1, arg2, arg3) {
        (ValueRef::Scalar(None), _, _)
        | (_, ValueRef::Scalar(None), _)
        | (_, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
        ) => Value::Scalar(Some(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        )),
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2)), ValueRef::Scalar(Some(arg3))) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2), ValueRef::Scalar(Some(arg3))) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Scalar(Some(arg3))) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Scalar(Some(arg2)), ValueRef::Column(arg3)) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2)), ValueRef::Column(arg3)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
    }
}

pub fn passthrough_nullable_4_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    O: ArgType,
>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        &mut EvalContext,
    ) -> Value<O>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    ValueRef<'a, NullableType<I4>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, ctx| match (arg1, arg2, arg3, arg4) {
        (ValueRef::Scalar(None), _, _, _)
        | (_, ValueRef::Scalar(None), _, _)
        | (_, _, ValueRef::Scalar(None), _)
        | (_, _, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => Value::Scalar(Some(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        )),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = arg4.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
    }
}

pub fn passthrough_nullable_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        ValueRef<'a, I5>,
        &mut EvalContext,
    ) -> Value<O>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    ValueRef<'a, NullableType<I4>>,
    ValueRef<'a, NullableType<I5>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, arg5, ctx| match (arg1, arg2, arg3, arg4, arg5) {
        (ValueRef::Scalar(None), _, _, _, _)
        | (_, ValueRef::Scalar(None), _, _, _)
        | (_, _, ValueRef::Scalar(None), _, _)
        | (_, _, _, ValueRef::Scalar(None), _)
        | (_, _, _, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => Value::Scalar(Some(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        )),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg4.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = arg5.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg4.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(
                        &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                        &arg3.validity,
                    ),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            Value::Column(NullableColumn { column, validity })
        }
    }
}

pub fn combine_nullable_1_arg<I1: ArgType, O: ArgType>(
    func: impl for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<NullableType<O>>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(ValueRef<'a, NullableType<I1>>, &mut EvalContext) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, ctx| match (arg1) {
        (ValueRef::Scalar(None)) => Value::Scalar(None),
        (ValueRef::Scalar(Some(arg1))) => {
            Value::Scalar(func(ValueRef::Scalar(arg1), ctx).into_scalar().unwrap())
        }
        (ValueRef::Column(arg1)) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(ValueRef::Column(arg1.column), ctx)
                .into_column()
                .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
    }
}

pub fn combine_nullable_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        &mut EvalContext,
    ) -> Value<NullableType<O>>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, ctx| match (arg1, arg2) {
        (ValueRef::Scalar(None), _) | (_, ValueRef::Scalar(None)) => Value::Scalar(None),
        (ValueRef::Scalar(Some(arg1)), ValueRef::Scalar(Some(arg2))) => Value::Scalar(
            func(ValueRef::Scalar(arg1), ValueRef::Scalar(arg2), ctx)
                .into_scalar()
                .unwrap(),
        ),
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2))) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(ValueRef::Column(arg1.column), ValueRef::Scalar(arg2), ctx)
                .into_column()
                .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2)) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(ValueRef::Scalar(arg1), ValueRef::Column(arg2.column), ctx)
                .into_column()
                .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
    }
}

pub fn combine_nullable_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        &mut EvalContext,
    ) -> Value<NullableType<O>>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, ctx| match (arg1, arg2, arg3) {
        (ValueRef::Scalar(None), _, _)
        | (_, ValueRef::Scalar(None), _)
        | (_, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
        ) => Value::Scalar(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        ),
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2)), ValueRef::Scalar(Some(arg3))) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2), ValueRef::Scalar(Some(arg3))) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Scalar(Some(arg3))) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Scalar(Some(arg2)), ValueRef::Column(arg3)) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Column(arg1), ValueRef::Scalar(Some(arg2)), ValueRef::Column(arg3)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Scalar(Some(arg1)), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (ValueRef::Column(arg1), ValueRef::Column(arg2), ValueRef::Column(arg3)) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
    }
}

pub fn combine_nullable_4_arg<I1: ArgType, I2: ArgType, I3: ArgType, I4: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        &mut EvalContext,
    ) -> Value<NullableType<O>>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    ValueRef<'a, NullableType<I4>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, ctx| match (arg1, arg2, arg3, arg4) {
        (ValueRef::Scalar(None), _, _, _)
        | (_, ValueRef::Scalar(None), _, _)
        | (_, _, ValueRef::Scalar(None), _)
        | (_, _, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => Value::Scalar(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        ),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = arg4.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
    }
}

pub fn combine_nullable_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        ValueRef<'a, I5>,
        &mut EvalContext,
    ) -> Value<NullableType<O>>
    + Copy
    + Send
    + Sync,
) -> impl for<'a> Fn(
    ValueRef<'a, NullableType<I1>>,
    ValueRef<'a, NullableType<I2>>,
    ValueRef<'a, NullableType<I3>>,
    ValueRef<'a, NullableType<I4>>,
    ValueRef<'a, NullableType<I5>>,
    &mut EvalContext,
) -> Value<NullableType<O>>
+ Copy
+ Send
+ Sync {
    move |arg1, arg2, arg3, arg4, arg5, ctx| match (arg1, arg2, arg3, arg4, arg5) {
        (ValueRef::Scalar(None), _, _, _, _)
        | (_, ValueRef::Scalar(None), _, _, _)
        | (_, _, ValueRef::Scalar(None), _, _)
        | (_, _, _, ValueRef::Scalar(None), _)
        | (_, _, _, _, ValueRef::Scalar(None)) => Value::Scalar(None),
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => Value::Scalar(
            func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_scalar()
            .unwrap(),
        ),
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg1.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg2.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg3.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg3.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = arg4.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Scalar(Some(arg5)),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg4.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Scalar(arg5),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = arg5.validity;
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Scalar(Some(arg4)),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg3.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Scalar(arg4),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity =
                databend_common_arrow::arrow::bitmap::and(&arg4.validity, &arg5.validity);
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Scalar(Some(arg3)),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Scalar(arg3),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(&arg3.validity, &arg4.validity),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Scalar(Some(arg2)),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg3.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Scalar(arg2),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Scalar(Some(arg1)),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(&arg2.validity, &arg3.validity),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Scalar(arg1),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
        (
            ValueRef::Column(arg1),
            ValueRef::Column(arg2),
            ValueRef::Column(arg3),
            ValueRef::Column(arg4),
            ValueRef::Column(arg5),
        ) => {
            let and_validity = databend_common_arrow::arrow::bitmap::and(
                &databend_common_arrow::arrow::bitmap::and(
                    &databend_common_arrow::arrow::bitmap::and(
                        &databend_common_arrow::arrow::bitmap::and(&arg1.validity, &arg2.validity),
                        &arg3.validity,
                    ),
                    &arg4.validity,
                ),
                &arg5.validity,
            );
            let validity = ctx
                .validity
                .as_ref()
                .map(|valid| valid & (&and_validity))
                .unwrap_or(and_validity);
            ctx.validity = Some(validity.clone());
            let nullable_column = func(
                ValueRef::Column(arg1.column),
                ValueRef::Column(arg2.column),
                ValueRef::Column(arg3.column),
                ValueRef::Column(arg4.column),
                ValueRef::Column(arg5.column),
                ctx,
            )
            .into_column()
            .unwrap();
            let combine_validity =
                databend_common_arrow::arrow::bitmap::and(&validity, &nullable_column.validity);
            Value::Column(NullableColumn {
                column: nullable_column.column,
                validity: combine_validity,
            })
        }
    }
}

fn erase_calc_domain_generic_0_arg<O: ArgType>(
    func: impl Fn(&FunctionContext) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| func(ctx).map(O::upcast_domain)
}

fn erase_calc_domain_generic_1_arg<I1: ArgType, O: ArgType>(
    func: impl Fn(&FunctionContext, &I1::Domain) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| {
        let arg1 = I1::try_downcast_domain(&args[0]).unwrap();
        func(ctx, &arg1).map(O::upcast_domain)
    }
}

fn erase_calc_domain_generic_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl Fn(&FunctionContext, &I1::Domain, &I2::Domain) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| {
        let arg1 = I1::try_downcast_domain(&args[0]).unwrap();
        let arg2 = I2::try_downcast_domain(&args[1]).unwrap();
        func(ctx, &arg1, &arg2).map(O::upcast_domain)
    }
}

fn erase_calc_domain_generic_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl Fn(&FunctionContext, &I1::Domain, &I2::Domain, &I3::Domain) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| {
        let arg1 = I1::try_downcast_domain(&args[0]).unwrap();
        let arg2 = I2::try_downcast_domain(&args[1]).unwrap();
        let arg3 = I3::try_downcast_domain(&args[2]).unwrap();
        func(ctx, &arg1, &arg2, &arg3).map(O::upcast_domain)
    }
}

fn erase_calc_domain_generic_4_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    O: ArgType,
>(
    func: impl Fn(
        &FunctionContext,
        &I1::Domain,
        &I2::Domain,
        &I3::Domain,
        &I4::Domain,
    ) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| {
        let arg1 = I1::try_downcast_domain(&args[0]).unwrap();
        let arg2 = I2::try_downcast_domain(&args[1]).unwrap();
        let arg3 = I3::try_downcast_domain(&args[2]).unwrap();
        let arg4 = I4::try_downcast_domain(&args[3]).unwrap();
        func(ctx, &arg1, &arg2, &arg3, &arg4).map(O::upcast_domain)
    }
}

fn erase_calc_domain_generic_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl Fn(
        &FunctionContext,
        &I1::Domain,
        &I2::Domain,
        &I3::Domain,
        &I4::Domain,
        &I5::Domain,
    ) -> FunctionDomain<O>,
) -> impl Fn(&FunctionContext, &[Domain]) -> FunctionDomain<AnyType> {
    move |ctx, args| {
        let arg1 = I1::try_downcast_domain(&args[0]).unwrap();
        let arg2 = I2::try_downcast_domain(&args[1]).unwrap();
        let arg3 = I3::try_downcast_domain(&args[2]).unwrap();
        let arg4 = I4::try_downcast_domain(&args[3]).unwrap();
        let arg5 = I5::try_downcast_domain(&args[4]).unwrap();
        func(ctx, &arg1, &arg2, &arg3, &arg4, &arg5).map(O::upcast_domain)
    }
}

fn erase_function_generic_0_arg<O: ArgType>(
    func: impl for<'a> Fn(&mut EvalContext) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| Value::upcast(func(ctx))
}

fn erase_function_generic_1_arg<I1: ArgType, O: ArgType>(
    func: impl for<'a> Fn(ValueRef<'a, I1>, &mut EvalContext) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| {
        let arg1 = args[0].try_downcast().unwrap();
        Value::upcast(func(arg1, ctx))
    }
}

fn erase_function_generic_2_arg<I1: ArgType, I2: ArgType, O: ArgType>(
    func: impl for<'a> Fn(ValueRef<'a, I1>, ValueRef<'a, I2>, &mut EvalContext) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| {
        let arg1 = args[0].try_downcast().unwrap();
        let arg2 = args[1].try_downcast().unwrap();
        Value::upcast(func(arg1, arg2, ctx))
    }
}

fn erase_function_generic_3_arg<I1: ArgType, I2: ArgType, I3: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        &mut EvalContext,
    ) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| {
        let arg1 = args[0].try_downcast().unwrap();
        let arg2 = args[1].try_downcast().unwrap();
        let arg3 = args[2].try_downcast().unwrap();
        Value::upcast(func(arg1, arg2, arg3, ctx))
    }
}

fn erase_function_generic_4_arg<I1: ArgType, I2: ArgType, I3: ArgType, I4: ArgType, O: ArgType>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        &mut EvalContext,
    ) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| {
        let arg1 = args[0].try_downcast().unwrap();
        let arg2 = args[1].try_downcast().unwrap();
        let arg3 = args[2].try_downcast().unwrap();
        let arg4 = args[3].try_downcast().unwrap();
        Value::upcast(func(arg1, arg2, arg3, arg4, ctx))
    }
}

fn erase_function_generic_5_arg<
    I1: ArgType,
    I2: ArgType,
    I3: ArgType,
    I4: ArgType,
    I5: ArgType,
    O: ArgType,
>(
    func: impl for<'a> Fn(
        ValueRef<'a, I1>,
        ValueRef<'a, I2>,
        ValueRef<'a, I3>,
        ValueRef<'a, I4>,
        ValueRef<'a, I5>,
        &mut EvalContext,
    ) -> Value<O>,
) -> impl Fn(&[ValueRef<AnyType>], &mut EvalContext) -> Value<AnyType> {
    move |args, ctx| {
        let arg1 = args[0].try_downcast().unwrap();
        let arg2 = args[1].try_downcast().unwrap();
        let arg3 = args[2].try_downcast().unwrap();
        let arg4 = args[3].try_downcast().unwrap();
        let arg5 = args[4].try_downcast().unwrap();
        Value::upcast(func(arg1, arg2, arg3, arg4, arg5, ctx))
    }
}
